package com.cqjtu.eecs.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.cqjtu.eecs.entity.*;
import com.cqjtu.eecs.entity.dto.CourseBackGraduateDTO;
import com.cqjtu.eecs.entity.vo.CourseBackGraduateVO;
import com.cqjtu.eecs.exception.NotFoundException;
import com.cqjtu.eecs.mapper.*;
import com.cqjtu.eecs.service.ICourseBackGraduateRequirementTemplateService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.cqjtu.eecs.utils.Assert;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.stream.Collectors;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author luojun
 * @since 2022-02-28
 */
@Service
public class CourseBackGraduateRequirementTemplateServiceImpl
        extends ServiceImpl<CourseBackGraduateRequirementTemplateMapper,
        CourseBackGraduateRequirementTemplate>
        implements ICourseBackGraduateRequirementTemplateService {

    private final TrainingProjectMapper trainingProjectMapper;
    private final GraduateRequirementTemplateMapper graduateRequirementTemplateMapper;
    private final CourseBackGraduateRequirementTemplateMapper courseBackGraduateRequirementTemplateMapper;
    private final CourseMapper courseMapper;
    private final TrainingProjectCourseMapper trainingProjectCourseMapper;

    public CourseBackGraduateRequirementTemplateServiceImpl(
            TrainingProjectMapper trainingProjectMapper,
            GraduateRequirementTemplateMapper graduateRequirementTemplateMapper,
            CourseBackGraduateRequirementTemplateMapper courseBackGraduateRequirementTemplateMapper,
            CourseMapper courseMapper, TrainingProjectCourseMapper trainingProjectCourseMapper
    ) {
        this.trainingProjectMapper = trainingProjectMapper;
        this.graduateRequirementTemplateMapper = graduateRequirementTemplateMapper;
        this.courseBackGraduateRequirementTemplateMapper = courseBackGraduateRequirementTemplateMapper;
        this.courseMapper = courseMapper;
        this.trainingProjectCourseMapper = trainingProjectCourseMapper;
    }

    /**
     * 获取毕业要求-课程实现矩阵
     * @return
     */
    @Override
    public CourseBackGraduateVO getCourseBackGraduateRequirementTemplate(String majorCode) {
        // 获取专业对应的模板
        TrainingProject trainingProject = trainingProjectMapper
                .selectOne(new LambdaQueryWrapper<TrainingProject>().eq(TrainingProject::getMajorCode, majorCode));
        Assert.notNull(trainingProject, new NotFoundException("该专业不存在对应的模板"));
        // 模板下的毕业要求list
        List<GraduateRequirementTemplate> graduateRequirementTemplates = graduateRequirementTemplateMapper
                .selectList(new LambdaQueryWrapper<GraduateRequirementTemplate>()
                .eq(GraduateRequirementTemplate::getMajorCode, majorCode)
        );
        Map<Integer, String> IdToCode = graduateRequirementTemplates.stream().collect(Collectors
                .toMap(GraduateRequirementTemplate::getGraduateRequirementId, GraduateRequirementTemplate::getGraduateRequirementCode));

        // 生成毕业要求的IdList
        List<Integer> IdList = graduateRequirementTemplates.stream()
                .map(GraduateRequirementTemplate::getGraduateRequirementId)
                .collect(Collectors.toList());
        // 通过毕业要求IdList获取全部课程支撑
        List<CourseBackGraduateRequirementTemplate> courseBackGraduateRequirementTemplates =
                courseBackGraduateRequirementTemplateMapper.listCourseBackGraduateRequirementTemplateByIdList(IdList);
        // 获取codeList
//        List<String> codeList = new ArrayList<>(courseBackGraduateRequirementTemplates.stream()
//                .map(CourseBackGraduateRequirementTemplate::getCourseCode)
//                .collect(Collectors.toSet()));

        // 通过majorCode获取课程的idList
        List<TrainingProjectCourse> trainingProjectCourseList = trainingProjectCourseMapper
                .selectList(new LambdaQueryWrapper<TrainingProjectCourse>()
                .eq(TrainingProjectCourse::getMajorCode, majorCode));
        List<Integer> idList = trainingProjectCourseList.stream()
                .map(TrainingProjectCourse::getCourseId).collect(Collectors.toList());
        // 课程code到id的映射
        Map<String, Integer> courseCodeToId = trainingProjectCourseList.stream().collect(Collectors
                .toMap(TrainingProjectCourse::getCourseCode, TrainingProjectCourse::getCourseId));
        List<Course> courses = courseMapper.listCourseByIdList(idList);
        // 课程id到课程名的映射
        Map<Integer, String> collect = courses.stream().collect(Collectors.toMap(Course::getCourseId, Course::getCourseName));
        // 1.获取一级毕业要求总数
        Integer graduateTopCount = new Integer(0);
        Iterator<GraduateRequirementTemplate> iterator = graduateRequirementTemplates.iterator();
        while (iterator.hasNext()){
            if (iterator.next().getPreGraduateRequirementId() == null)
                graduateTopCount++;
        }
        // 2.获取二级毕业要求数量
        Map<String, Integer> graduateCount = new HashMap<>();
        for (int i = 1; i <= graduateTopCount; i++) {
            graduateCount.put(String.valueOf(i), 0);
        }
        iterator = graduateRequirementTemplates.iterator();
        while (iterator.hasNext()){
            GraduateRequirementTemplate next = iterator.next();
            if (next.getPreGraduateRequirementId() != null){
                graduateCount.put(next.getPreGraduateRequirementId(), graduateCount.get(next.getPreGraduateRequirementId())+1);
            }
        }

        // 3.课程对应的支撑
        List<CourseBackGraduateDTO> courseBackGraduateDTOS = new ArrayList<>();
        Iterator<TrainingProjectCourse> iterator1 = trainingProjectCourseList.iterator();
        while (iterator1.hasNext()){
            TrainingProjectCourse item = iterator1.next();
//            System.out.println(item);
            CourseBackGraduateDTO courseBackGraduateDTO = new CourseBackGraduateDTO();
            courseBackGraduateDTO.setCourseName(collect.get(courseCodeToId.get(item.getCourseCode())));
            Map<String, Float> courseGraduateMap = new HashMap<>();
            // 获取毕业要求对应的权重
            Iterator<CourseBackGraduateRequirementTemplate> it = courseBackGraduateRequirementTemplates.iterator();
            while (it.hasNext()){
                CourseBackGraduateRequirementTemplate next = it.next();
//                System.out.println(next);
                if (next.getCourseCode().equals(item.getCourseCode())){
//                    System.out.println("yes");
                    courseGraduateMap.put(IdToCode.get(next.getGraduateRequirementId()),
                            next.getCourseGraduateRequirementBackWeight());
                }
            }
            // 将结果加入
            courseBackGraduateDTO.setCourseGraduateMap(courseGraduateMap);
//            System.out.println(courseBackGraduateDTO);
            if (courseBackGraduateDTO.getCourseGraduateMap().size() > 0)
                courseBackGraduateDTOS.add(courseBackGraduateDTO);
        }
        CourseBackGraduateVO courseBackGraduateVO =
                new CourseBackGraduateVO(graduateTopCount, graduateCount, courseBackGraduateDTOS);
        return courseBackGraduateVO;
    }
}
